package com.apes.fn.scm.income.distributionOrder.serivce;

import com.apes.fn.scm.income.distributionOrder.model.DistributionOrder;
import com.apes.fn.scm.income.distributionOrder.repository.DistributionOrderRepository;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.repository.RetailOrderRepository;
import com.apes.fn.scm.retailReturn.RetailReturn;
import com.apes.fn.scm.retailReturn.RetailReturnRepository;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.Arith;
import com.apes.framework.util.MapUtil;
import com.apes.scm.account.account.repository.CooperationRepository;
import com.apes.scm.account.tax.repository.TaxRepository;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.contract.repository.ContractRepository;
import com.apes.scm.income.model.Income;
import com.apes.scm.income.model.IncomeItem;
import com.apes.scm.income.service.SupplierIncomeService;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.finance.repository.IncomeTypeRepository;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.voucher.model.Voucher;
import com.apes.scm.voucher.repository.VoucherRepository;
import com.apestech.framework.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;


@Service
public class DistributionOrderService extends DomainService {

    @Autowired
    private DistributionOrderRepository distributionOrderRepository;
    @Autowired
    private SupplierIncomeService supplierIncomeService;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private CooperationRepository cooperationRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private TaxRepository taxRepository;
    @Autowired
    private IncomeTypeRepository incomeTypeRepository;
    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private RetailOrderRepository retailOrderRepository;
    @Autowired
    private RetailReturnRepository retailReturnRepository;
    @Autowired
    private ServicePlanRepository servicePlanRepository;


    public Object distribution(SimpleRequest request){
        DistributionOrder distributionOrder = request.getO(DistributionOrder.class);
        DistributionOrder oldDistributionOrder = distributionOrderRepository.findAll(JpaDsl.toCriteriaByEq("retailOrderId", distributionOrder.getRetailOrderId())).stream().findFirst().orElse(null);
        if (oldDistributionOrder != null) return mapper("id",oldDistributionOrder.getId());
        distributionOrder.setCompany(deptRepository.findOne(distributionOrder.getBelongDept().getId()).getCompany());
        ServicePlan servicePlan = servicePlanRepository.findOneBySourceFrom(distributionOrder.getAppSourceBusinessKey());
        distributionOrder.setSourceBusinessKey(servicePlan != null ? servicePlan.getId() : null);
        switch (distributionOrder.getState()){
            case "yearCard":
            case "service": createAndApprove(distributionOrder,true);break;
            case "yearCardReturn":
            case "serviceReturn":createAndApprove(distributionOrder,false); break;
            default:throw new RuntimeException("源单据类型不匹配");
        }
        return mapper("id",distributionOrderRepository.saveAndFlush(distributionOrder).getId());
    }

    private void createAndApprove(DistributionOrder distributionOrder,boolean flag){
        double distributionCommissionAmount = distributionOrder.getDistributionCommissionAmount();
        double distributionServiceAmount = distributionOrder.getDistributionServiceAmount();
        // true为正向流程
        if (flag){
            setManageReliefAmount(distributionOrder,flag);
            incomeSupplierCreateAndApprove(distributionOrder,5L,"A15",flag,distributionCommissionAmount,"订单分销，分销佣金自动创建供应商收入单，车牌号码");
            incomeSupplierCreateAndApprove(distributionOrder,4L,"A16",flag,distributionServiceAmount,"订单分销，分销服务费自动创建供应商收入单，车牌号码");
            incomeCustomerCreateAndApprove(distributionOrder,5L,"A15",flag,distributionCommissionAmount,"订单分销，分销佣金自动创建客户返利单，车牌号码");
            incomeCustomerCreateAndApprove(distributionOrder,4L,"A16",flag,distributionServiceAmount,"订单分销，分销服务费自动创建客户返利单，车牌号码");
        }else{
            setManageReliefAmount(distributionOrder,flag);
            if (distributionCommissionAmount != 0){
                incomeSupplierCreateAndApprove(distributionOrder,4L,"A16",flag,distributionServiceAmount,"订单分销，分销服务费自动创建供应商收入单，车牌号码");
                incomeCustomerCreateAndApprove(distributionOrder,4L,"A16",flag,distributionServiceAmount,"订单分销，分销服务费自动创建客户返利单，车牌号码");
            }
            if (distributionOrder.getBearPlatform() != 0){
                incomeSupplierCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearPlatform(),"订单分销，平台承担自动创建供应商收入单，车牌号码");
                incomeCustomerCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearPlatform(),"订单分销，平台承担自动创建客户返利单，车牌号码");
            }
            if (distributionOrder.getBearDistribution() != 0){
                incomeSupplierCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearDistribution(),"订单分销，分销员承担自动创建供应商收入单，车牌号码");
                incomeCustomerCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearDistribution(),"订单分销，分销员承担自动创建客户返利单，车牌号码");
            }
            if (distributionOrder.getBearDept() != 0){
                incomeSupplierCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearDept(),"订单分销，门店承担自动创建供应商收入单，车牌号码");
                incomeCustomerCreateAndApprove(distributionOrder,4L,"A15",flag,distributionOrder.getBearDept(),"订单分销，门店承担自动创建客户返利单，车牌号码");
            }
        }
    }

    /**
     * 供应商收入单
     * @param distributionOrder
     * @param taxId
     * @param incomeType
     * @param flag
     * @param incomeAmount
     * @param note
     */
    private void incomeSupplierCreateAndApprove(DistributionOrder distributionOrder,Long taxId,String incomeType,boolean flag,double incomeAmount,String note){
        if(incomeAmount == 0) return;
        Income income = new Income();
        income.setCreator("system");
        income.setApproveUID(partyRoleRepository.findOne("system"));
        income.setCompany(partyRoleRepository.findOne("1007"));
        income.setPartner(partyRoleRepository.findPartyBySupplier(distributionOrder.getCompany().getId()));
        income.setCooperation(cooperationRepository.findOne("distribution"));
        income.setInComeCategory(enumerationRepository.findOne("cost"));
        income.setSource(distributionOrder.getRetailOrderId());
        income.setOrigin(distributionOrder.getAppSourceBusinessKey());
        income.setSourceBusinessKey(distributionOrder.getAppSourceBusinessKey());
        RetailOrder retailOrder = retailOrderRepository.findOne(distributionOrder.getRetailOrderId());
        if (retailOrder != null) {
            income.setCarLicense(retailOrder.getCustomerExpand().getCarLicense());
            distributionOrder.setCarNumber(retailOrder.getCustomerExpand().getCarLicense());
        }else{
            RetailReturn retailReturn = retailReturnRepository.findOne(distributionOrder.getRetailOrderId());
            income.setCarLicense(retailReturn.getCustomerExpand().getCarLicense());
            distributionOrder.setCarNumber(retailOrder.getCustomerExpand().getCarLicense());
        }
        income.setNote(note + income.getCarLicense());
        Set<IncomeItem> incomeItems = new HashSet();
        IncomeItem incomeItem = new IncomeItem();
        incomeItem.setIncomeType(incomeTypeRepository.findOne(incomeType));
        incomeItem.setTax(taxRepository.findOne(taxId));
        incomeItem.setIncomeAmount(incomeAmount);
        incomeItem.setStartDate(new Date());
        incomeItem.setEndDate(new Date());
        incomeItem.setNote("[" + distributionOrder.getBelongDept().getId() + "]" + distributionOrder.getBelongDept().getName());
        incomeItems.add(incomeItem);
        income.setIncomeItems(incomeItems);


        SimpleRequest simpleRequest = new SimpleRequest();
        simpleRequest.setBody(new JSONObject((Map)MapUtil.mapped(income)).toString());
        Income createIncome = supplierIncomeService.create(simpleRequest);
        SimpleRequest approveRe = new SimpleRequest();
        approveRe.setBody(new JSONObject((Map)MapUtil.mapped(createIncome)).toString());
        supplierIncomeService.approve(approveRe);
    }

    /**
     * 客户返利单
     * @param distributionOrder
     * @param taxId
     * @param incomeType
     * @param flag
     * @param incomeAmount
     * @param note
     */
    private void incomeCustomerCreateAndApprove(DistributionOrder distributionOrder,Long taxId,String incomeType,boolean flag,double incomeAmount,String note){
        if(incomeAmount == 0) return;
        Income income = new Income();
        income.setCreator("system");
        income.setApproveUID(partyRoleRepository.findOne("system"));
        income.setCompany(distributionOrder.getCompany());
        income.setDept(distributionOrder.getBelongDept());
        income.setCooperation(cooperationRepository.findOne("distribution"));
        income.setPartner(partyRoleRepository.findOne("K1007"));
        income.setInComeCategory(enumerationRepository.findOne("cost"));
        income.setSource(distributionOrder.getRetailOrderId());
        income.setOrigin(distributionOrder.getAppSourceBusinessKey());
        income.setSourceBusinessKey(distributionOrder.getAppSourceBusinessKey());
        RetailOrder retailOrder = retailOrderRepository.findOne(distributionOrder.getRetailOrderId());
        if (retailOrder != null) {
            income.setCarLicense(retailOrder.getCustomerExpand().getCarLicense());
            distributionOrder.setCarNumber(retailOrder.getCustomerExpand().getCarLicense());
        }else{
            RetailReturn retailReturn = retailReturnRepository.findOne(distributionOrder.getRetailOrderId());
            income.setCarLicense(retailReturn.getCustomerExpand().getCarLicense());
            distributionOrder.setCarNumber(retailOrder.getCustomerExpand().getCarLicense());
        }
        income.setNote(note + income.getCarLicense());
        Set<IncomeItem> incomeItems = new HashSet();
        IncomeItem incomeItem = new IncomeItem();
        incomeItem.setIncomeType(incomeTypeRepository.findOne(incomeType));
        incomeItem.setTax(taxRepository.findOne(taxId));
        incomeItem.setIncomeAmount(incomeAmount);
        incomeItem.setStartDate(new Date());
        incomeItem.setEndDate(new Date());
        incomeItems.add(incomeItem);
        incomeItem.setNote("[" + distributionOrder.getBelongDept().getId() + "]" + distributionOrder.getBelongDept().getName());
        income.setIncomeItems(incomeItems);

        SimpleRequest simpleRequest = new SimpleRequest();
        simpleRequest.setBody(new JSONObject((Map)MapUtil.mapped(income)).toString());
        Income createIncome = supplierIncomeService.create(simpleRequest);
        SimpleRequest approveRe = new SimpleRequest();
        approveRe.setBody(new JSONObject((Map)MapUtil.mapped(createIncome)).toString());
        supplierIncomeService.approve(approveRe);
    }

    private void setManageReliefAmount(DistributionOrder distributionOrder,boolean flag){
        Map<String, Object> strategyMap = new HashMap<>();
        strategyMap.put("COMPANY_ID", distributionOrder.getBelongDept().getCompany().getId());
        strategyMap.put("OPERATION", distributionOrder.getBelongDept().getCompany().getParty().getCorporate().getOperation().getId());
        strategyMap.put("SYS_RQ", new Date());
        strategyMap.put("conditionId", "FW01");
        //取平台服务费
        Object invoke = this.invoke("condition.getCondition", strategyMap);
        BigDecimal T001 = ((JSONObject) invoke).getBigDecimal("T001");
        if (T001 == null){
            distributionOrder.setManageReliefAmount(0);
            return;
        }
        double add = 0;
        if (flag){
            add = Arith.add(distributionOrder.getDistributionCommissionAmount(), distributionOrder.getDistributionServiceAmount());
        }else{
            add = Arith.add(distributionOrder.getBearDept(),distributionOrder.getBearDistribution());
            add = Arith.add(distributionOrder.getBearPlatform(),add);
            add = Arith.add(distributionOrder.getDistributionServiceAmount(),add);
        }
        distributionOrder.setManageReliefAmount(Arith.mul(add,T001.doubleValue()));
    }
}
